package inventory.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import inventory.entity.Equipment;
import inventory.entity.InRepositoryRecord;
import inventory.entity.MaterialStuff;
import inventory.entity.Terminal;
import inventory.entity.bo.MaterialBo;
import inventory.entity.po.InRepositoryRecordPo;
import inventory.mappers.*;
import inventory.service.InRepositoryRecordService;
import inventory.utils.MaterialInitUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sxt
 * @since 2019-11-06
 */
@Service
public class InRepositoryRecordServiceImpl extends ServiceImpl<InRepositoryRecordMapper, InRepositoryRecord> implements InRepositoryRecordService {

    @Resource
    private InRepositoryRecordPoMapper inRepositoryRecordPoMapper;

    @Resource
    private InRepositoryRecordMapper inRepositoryRecordMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private TerminalMapper terminalMapper;

    @Resource
    private EquipmentMapper equipmentMapper;

    @Resource
    private MaterialStuffMapper materialStuffMapper;


    @Override
    public List<InRepositoryRecordPo> queryAllInRepositoryRecordPo(String roleId) {
        List<InRepositoryRecordPo> inRepositoryRecordPos = inRepositoryRecordPoMapper.selectList(new EntityWrapper<InRepositoryRecordPo>()
        .eq("role_id",roleId));
        return inRepositoryRecordPos;
    }

    @Override
    public List<InRepositoryRecordPo> queryInRepositoryRecordPoByCondition(Map<String, Object> columnMap) {
        List<InRepositoryRecordPo> inRepositoryRecordPos = inRepositoryRecordPoMapper.selectByMap(columnMap);
        return inRepositoryRecordPos;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public boolean addTerminal(Terminal terminal, InRepositoryRecord inRepositoryRecord) {
        boolean rs1 = terminal.insertOrUpdate();
        boolean rs2 = inRepositoryRecord.insertOrUpdate();
        return rs1 && rs2;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public boolean addEquipment(Equipment equipment, InRepositoryRecord inRepositoryRecord) {
        boolean rs1 = equipment.insertOrUpdate();
        boolean rs2 = inRepositoryRecord.insertOrUpdate();
        return rs1 && rs2;
    }

    @Override
    public boolean addStuff(MaterialStuff materialStuff, InRepositoryRecord inRepositoryRecord) {
        boolean rs1 = materialStuff.insertOrUpdate();
        boolean rs2 = inRepositoryRecord.insertOrUpdate();
        return rs1 && rs2;
    }

    @Override
    public List<InRepositoryRecordPo> queryInRepositoryByTimePeriod(Date startTime, Date endTime) {
        List<InRepositoryRecordPo> inRepositoryRecordPos = inRepositoryRecordPoMapper.selectList(new EntityWrapper<InRepositoryRecordPo>()
                .between("in_time", startTime, endTime));
        return inRepositoryRecordPos;
    }

    @Transactional
    @Override
    public boolean outTerminal(MaterialBo materialBo, InRepositoryRecord inRepositoryRecord, List<String> imeis) {

        Terminal tempTerminal = new Terminal(); //临时变量，用来存取每一次的imei，以便下面查询

        long count = 0L;

        for (String imei : imeis) {
            tempTerminal.setImei(imei);//设置当前的imei
            //查询对应imei终端信息
            Terminal terminal = terminalMapper.selectOne(tempTerminal);
            if(terminal==null || !terminal.getRepositoryId().equals(inRepositoryRecord.getSource()) ){
                //判断如果为空，或者不是本仓库的，则continue
                continue;
            }
            terminal.setRepositoryId(materialBo.getTargetRepositoryId());   //更新所在仓库
            terminal.setStorageTime(new Date());    //更新入库时间
            terminal.setTrace(terminal.getTrace()+" -> "+terminal.getRepositoryId());

            inRepositoryRecord.setCount(inRepositoryRecord.getCount() + 1);//数量+1
            //更新terminal表
            terminalMapper.updateById(terminal);

            count++;
        }
        //插入出库的记录
        if (count!=0){
            inRepositoryRecord.setCount(count);
            inRepositoryRecordMapper.insert(inRepositoryRecord);
            return true;
        }

        return false;
    }

    @Transactional
    @Override
    public boolean outEquipment(MaterialBo materialBo, InRepositoryRecord inRepositoryRecord, List<String> imeis) {

        Equipment tempEquipment = new Equipment(); //临时变量，用来存取每一次的imei，以便下面查询

        long count = 0L;

        for (String imei : imeis) {
            tempEquipment.setImei(imei);//设置当前的imei
            //查询对应imei终端信息
            Equipment equipment = equipmentMapper.selectOne(tempEquipment);
            if (equipment==null || !equipment.getRepositoryId().equals(inRepositoryRecord.getSource())){
                //判断如果为空，或者不是本仓库的，则continue
                continue;
            }
            equipment.setRepositoryId(materialBo.getTargetRepositoryId());   //更新所在仓库
            equipment.setStorageTime(new Date());    //更新入库时间
            equipment.setTrace(equipment.getTrace()+" -> "+equipment.getRepositoryId());

            inRepositoryRecord.setCount(inRepositoryRecord.getCount() + 1);//数量+1
            //更新equipment表
            equipmentMapper.updateById(equipment);

            count++;
        }
        //插入出库的记录
        if (count!=0){
            inRepositoryRecord.setCount(count);
            inRepositoryRecordMapper.insert(inRepositoryRecord);
            return true;
        }

        return false;
    }

    @Transactional
    @Override
    public boolean outMaterialStuff(MaterialBo materialBo, InRepositoryRecord inRepositoryRecord) {
        MaterialStuff materialStuff = materialStuffMapper.selectById(materialBo.getStuffId());
        if (materialStuff == null){
            return false;
        }
        //判断要出库的数量 与 当前物料记录的剩余数量 的大小
        if (materialStuff.getInRepository()<=materialBo.getCount()){
            //如果大于等于，则出库数量变为最大值，库存数量变为0
            materialStuff.setOutRepository(materialStuff.getInRepository() + materialStuff.getInRepository());
            materialStuff.setInRepository(0L);
            materialStuff.setSaleTime(new Date());//设置本条记录库存为0的时间
        }else {
            //如果小于，则正常出库
            materialStuff.setInRepository(materialStuff.getInRepository()-materialBo.getCount());
            materialStuff.setOutRepository(materialStuff.getOutRepository()+materialBo.getCount());
        }
        //针对于旧的作出库操作
        materialStuffMapper.updateById(materialStuff);

        //针对于新的作插入新记录
        MaterialStuff materialStuffNew = MaterialInitUtil.initMaterialStuff(materialBo);
        materialStuffMapper.insert(materialStuffNew);

        //添加出入库记录
        inRepositoryRecordMapper.insert(inRepositoryRecord);

        return true;

    }

    @Transactional
    @Override
    public boolean outMaterialStuff(Map<String, Object> map, MaterialBo materialBo,InRepositoryRecord inRepositoryRecord) {

        //定义的当前的数量
        Integer count = 0;

        for (String key : map.keySet()){
            Integer value = (Integer)map.get(key);
            MaterialStuff materialStuff = materialStuffMapper.selectById(key);
            if (materialStuff == null){
                continue;
            }
            //判断要出库的数量 与 当前物料记录的剩余数量 的大小
            if (materialStuff.getInRepository()<=value){
                //如果大于等于，则出库数量变为最大值，库存数量变为0
                materialStuff.setOutRepository(materialStuff.getInRepository() + materialStuff.getOutRepository());
                materialStuff.setInRepository(0L);
                materialStuff.setSaleTime(new Date());//设置本条记录库存为0的时间
            }else {
                //如果小于，则正常出库
                materialStuff.setInRepository(materialStuff.getInRepository()-value);
                materialStuff.setOutRepository(materialStuff.getOutRepository()+value);
            }
            //针对于旧的作出库操作
            materialStuffMapper.updateById(materialStuff);
            count+=value;
        }

        materialBo.setCount(count);
        //针对于新的作插入新记录
        MaterialStuff materialStuffNew = MaterialInitUtil.initMaterialStuff(materialBo);
        materialStuffMapper.insert(materialStuffNew);

        inRepositoryRecord.setCount(Long.valueOf(count));
        //添加出入库记录
        inRepositoryRecordMapper.insert(inRepositoryRecord);

        return true;
    }
}
